package com.lsx.logisticscore.controller;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.lsx.logistics.AssertUtil;
import com.lsx.logistics.JwtUtil;
import com.lsx.logistics.response.CommonResp;
import com.lsx.logisticscore.entity.Account;
import com.lsx.logisticscore.entity.Employee;
import com.lsx.logisticscore.entity.Resource;
import com.lsx.logisticscore.mapper.AccountMapper;
import com.lsx.logisticscore.mapper.EmployeeMapper;
import com.lsx.logisticscore.response.EmployeeResp;
import com.lsx.logisticscore.service.AdminService;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.util.Comparator;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

@Slf4j
@RestController
public class AdminController {
    @Autowired
    private AdminService adminService;
    @Autowired
    private AccountMapper accountMapper;
    @Autowired
    private EmployeeMapper employeeMapper;
    @Autowired
    private RedisTemplate<String, Employee> redisTemplate;
    @Value("${token.expiration}")
    private String expiration;
    @Value("${token.signature}")
    private String signature;
    @Value("${common.ip}")
    private String ip;

    @GetMapping("/getMenu")
    public CommonResp<List<Resource>> doGetMenu(@RequestHeader("X-Token") String token){
        String json = JwtUtil.getInfo(token, signature);
        JSONObject jb = JSONObject.parseObject(json);
        String role = jb.getString("role");
        log.info("===========获取资源的role为：{}", role);
        List<Resource> resources = adminService.getResourceByUser(role);
        // 排个序 到前端显示的时候好看一点
        resources.sort(new Comparator<Resource>() {
            @Override
            public int compare(Resource o1, Resource o2) {
                return o1.getChildren().size() - o2.getChildren().size();
            }
        });

        CommonResp<List<Resource>> resp = new CommonResp<>();
        if ( null == resources ){
            resp.setStatus("-1");
            resp.setMessage("角色无效");
        }
        resp.setContent(resources);
        return resp;
    }


    @PostMapping("/login")
    public CommonResp<String> doLogin(@RequestBody String jsonString){
        JSONObject js = JSONObject.parseObject(jsonString);

        String empId = js.getString("empId");
        String password = js.getString("password");

        log.info("$$$$$$$$传入的empId:{}, password:{}", empId, password);
        CommonResp<String> resp = new CommonResp<>();
        //获取主体对象
        Subject subject = SecurityUtils.getSubject();
        //封装用户数据
        UsernamePasswordToken token = new UsernamePasswordToken(empId, password);
        //执行登录方法
        try{
            subject.login(token);
        }catch (UnknownAccountException e){
            resp.setStatus("-1");
            resp.setMessage("用户不存在");
            System.out.println("用户不存在");
            return resp;
        }catch (IncorrectCredentialsException e){
            resp.setStatus("-2");
            resp.setMessage("密码错误");
            System.out.println("密码错误");
            return resp;
        }
        //验证通过 生成token
        QueryWrapper<Account> wrapper = new QueryWrapper<>();
        wrapper.eq("emp_id", empId);
        Account account1 = accountMapper.selectOne(wrapper);
        log.info("expiration = {}", expiration);
        String jwtToken = JwtUtil.getToken(account1.getEmpId(), account1.getRole(), Long.valueOf(expiration), signature);
        log.info("$$$$$$$$$$$ 登录之后返回的token为：{}", jwtToken);
        //查出对应的员工信息 保存到redis
        QueryWrapper<Employee> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("emp_id", empId);
        redisTemplate.opsForValue().set(jwtToken, employeeMapper.selectOne(queryWrapper), Long.valueOf(expiration), TimeUnit.MILLISECONDS);
        resp.setContent(jwtToken);
        return resp;
    }
    @RequestMapping("/getEmpInfo")
    public CommonResp<EmployeeResp> getEmpInfo(String token){
        //不用做token判断了 因为shiro做了
        log.info("传入的token值为：{}", token);
        CommonResp<EmployeeResp> resp = new CommonResp<>();
        String json = JwtUtil.getInfo(token, signature);
        JSONObject jb = JSONObject.parseObject(json);
        String empId = jb.getString("empId");
        log.info("得到的empId为：{}", empId);
        QueryWrapper<Employee> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("emp_id", empId);
        Employee employee = employeeMapper.selectOne(queryWrapper);
        QueryWrapper<Account> queryWrapper1 = new QueryWrapper<>();
        queryWrapper1.eq("emp_id", empId);
        Account account = accountMapper.selectOne(queryWrapper1);
        EmployeeResp response = new EmployeeResp();
        BeanUtils.copyProperties(employee, response);
        response.setAvatar(account.getAvatar());
        resp.setContent(response);
        return resp;
    }

    @RequestMapping("/logout")
    public CommonResp<String> doLogout(@RequestHeader("X-token") String token){
        CommonResp<String> resp = new CommonResp<>();
        redisTemplate.delete(token);
        return resp;
    }

    @RequestMapping("/uploadAvatar")
    public CommonResp<String> doAvatarUpload(@RequestParam("file")MultipartFile file) throws FileNotFoundException {
        String path = uploadFile(file);
        CommonResp<String> resp = new CommonResp<>();
        if (!AssertUtil.isEmpty(path)){
            resp.setContent(path);
        }
        return resp;
    }

    @RequestMapping("/updateAvatar")
    public CommonResp<String> doUpdateAvatar(@RequestBody JSONObject body){
        String empId = body.getString("empId");
        String path = body.getString("path");
        if (!AssertUtil.isEmpty(path)){
            QueryWrapper<Account> wrapper = new QueryWrapper<>();
            wrapper.eq("emp_id", empId);
            Account account = accountMapper.selectOne(wrapper);
            account.setAvatar(path);
            accountMapper.update(account, wrapper);
        }
        return new CommonResp<>();
    }
    private String uploadFile(MultipartFile file){
        log.info("fileName: {}", file.getOriginalFilename());
        String originalFilename = file.getOriginalFilename(); //完整的名字
        String suffix = originalFilename.split("\\.")[1]; //后缀
        String newName = UUID.randomUUID().toString() + "." + suffix; //新的名字
        File path = new File("/usr/local/image/");
        if (!path.exists()){
            path.mkdirs();
        }
        BufferedOutputStream bos = null;
        try {
            bos = new BufferedOutputStream(
                new FileOutputStream(new File("/usr/local/image/" + newName)));

            bos.write(file.getBytes());
            bos.flush();
            bos.close();
        } catch (IOException e) {
            e.printStackTrace();
            log.error("上传文件出错：{}", e);
            return null;
        }
        return ip + "/image/" + newName;
    }
    @RequestMapping("/saveNews")
    public CommonResp<String> saveNews(@RequestBody String content){
        log.info("content = {}", content);

        return new CommonResp<>("good");
    }
}
